package controllers

import (
	"anban/service"
	"anban/utils/wechat"
	"encoding/xml"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/logs"
	"net/url"
)

type NotifyController struct {
	beego.Controller
}

func (c *NotifyController) Prepare() {
	c.EnableXSRF = false
}

// 微信支付委托代扣-小程序纯签约异步通知
func (c *NotifyController) MiniProgram() {
	var p map[string]interface{}
	var editInput url.Values
	var ret string

	miniContractRes := wechat.MiniContractRes{}
	err := xml.Unmarshal(c.Ctx.Input.RequestBody, &miniContractRes)
	if err != nil {
		logs.Error("unmarshal mini contract response fail")
		ret = wechat.GetMiniContractRet("FAIL", "contract_code is empty")
		c.Ctx.WriteString(ret)
		return
	}

	if miniContractRes.ChangeType != "ADD" {
		logs.Error("mini contract response change type is not ADD")
		ret = wechat.GetMiniContractRet("FAIL", "contract_code is empty")
		c.Ctx.WriteString(ret)
		return
	}

	if len(miniContractRes.ContractCode) <= 0 {
		logs.Error("contract_code is empty")
		ret = wechat.GetMiniContractRet("FAIL", "contract_code is empty")
		c.Ctx.WriteString(ret)
		return
	}

	p = map[string]interface{}{}
	p["contract_code"] = miniContractRes.ContractCode
	miniProgramContract := service.GetMiniProgramContractInfo(p)
	if miniProgramContract.Id <= 0 {
		logs.Error("miniProgramContract record don't find")
		ret = wechat.GetMiniContractRet("FAIL", "miniProgramContract record don't find")
		c.Ctx.WriteString(ret)
		return
	}

	if miniContractRes.ReturnCode == "SUCCESS" && miniContractRes.ResultCode == "SUCCESS" {
		if !miniContractRes.CheckSign() {
			logs.Error("mini contract sign error")
			ret = wechat.GetMiniContractRet("FAIL", "sign error")
			c.Ctx.WriteString(ret)
			return
		}

		if miniProgramContract.Status != 1 {
			editInput = url.Values{
				"id":     {fmt.Sprintf("%d", miniProgramContract.Id)},
				"status": {"1"},
			}
			service.EditMiniProgramContract(editInput)

			userId := miniProgramContract.User.Id
			if userId > 0 {
				editInput = url.Values{
					"id":          {fmt.Sprintf("%d", userId)},
					"is_contract":      {"1"},
					"contract_id": {miniContractRes.ContractId},
					"contract_expire_time": {miniContractRes.ContractExpiredTime},
				}
				service.EditUser(editInput)
			}
		}

		ret = wechat.GetMiniContractRet("SUCCESS", "OK")
		c.Ctx.WriteString(ret)
		return
	} else {
		if miniProgramContract.Status != 2 {
			editInput = url.Values{
				"id":       {fmt.Sprintf("%d", miniProgramContract.Id)},
				"status":   {"2"},
				"fail_msg": {miniContractRes.ReturnMsg},
			}
			service.EditMiniProgramContract(editInput)
		}

		ret = wechat.GetMiniContractRet("FAIL", "result_code is fail")
		c.Ctx.WriteString(ret)
		return
	}
}

// 微信支付委托扣款异步通知
func (c *NotifyController) PapPayApply() {
	var p map[string]interface{}
	var addInput url.Values
	var editInput url.Values
	var ret string

	papPayApplyRes := wechat.PapPayApplyRes{}
	err := xml.Unmarshal(c.Ctx.Input.RequestBody, &papPayApplyRes)
	if err != nil {
		logs.Error("unmarshal mini papPayApply response fail")
		ret = wechat.GetMiniContractRet("FAIL", "contract_code is empty")
		c.Ctx.WriteString(ret)
		return
	}

	if len(papPayApplyRes.OutTradeNo) <= 0 {
		logs.Error("mini papPayApply out_trade_no is empty")
		ret = wechat.GetPapPayApplyRet("FAIL", "out_trade_no is empty")
		c.Ctx.WriteString(ret)
		return
	}

	p = map[string]interface{}{}
	p["sn"] = papPayApplyRes.OutTradeNo
	papPayApplyRecord := service.GetPapPayApplyRecordInfo(p)
	if papPayApplyRecord.Id <= 0 {
		logs.Error("payPayApplyRecord don't find")
		ret = wechat.GetPapPayApplyRet("FAIL", "payPayApplyRecord don't find")
		c.Ctx.WriteString(ret)
		return
	}

	if papPayApplyRes.ReturnCode == "SUCCESS" && papPayApplyRes.ResultCode == "SUCCESS" {
		if !papPayApplyRes.CheckSign() {
			logs.Error("mini papPayApply sign is error")
			ret = wechat.GetPapPayApplyRet("FAIL", "sign is error")
			c.Ctx.WriteString(ret)
			return
		}

		if papPayApplyRecord.Status != 1 {
			editInput = url.Values{
				"id": {fmt.Sprintf("%d", papPayApplyRecord.Id)},
				"status": {"1"},
				"bank_type": {papPayApplyRes.BankType},
				"transaction_id": {papPayApplyRes.TransactionId},
			}
			service.EditPapPayApplyRecord(editInput)

			addInput = url.Values{
				"user_id": {fmt.Sprintf("%d", papPayApplyRecord.User.Id)},
				"student_id": {fmt.Sprintf("%d", papPayApplyRecord.Student.Id)},
				"type": {"1"},
				"amount": {fmt.Sprintf("%f", papPayApplyRecord.Amount)},
			}
			service.AddFinance(addInput)
		}

		ret = wechat.GetPapPayApplyRet("SUCCESS", "OK")
		c.Ctx.WriteString(ret)
		return
	} else {
		if papPayApplyRecord.Status != 2 {
			editInput = url.Values{
				"id": {fmt.Sprintf("%d", papPayApplyRecord.Id)},
				"status": {"2"},
				"fail_msg": {papPayApplyRes.ReturnMsg},
			}
			service.EditPapPayApplyRecord(editInput)
		}
	}
}
